﻿/************************************************************************
** 文  件：
**	Engine.h
** 功  能：
**	AI识别引擎封装类
** 作  者：
**	email:lixx2048@163.com
**  wechat:lixiang6153
**  QQ:941415509
** 日  期：
**	2024/03/15	14:00:00
** 说  明：
**	无
** 版  本：
**	2024/03/15	14:00:00		1.0		lixx2048@163.com
/************************************************************************/
#pragma once
#include <queue>
#include <thread>
#include <memory>
#include <chrono>
#include <tuple>
#include <set>
#include "OcrItem.h"
#include "Inference.h"
#include "../entity/ModelInfo.h"
#include "../entity/SceneInfo.h"

class Engine
	: public std::enable_shared_from_this<Engine>
{
	// 识别列表
	typedef std::queue<OcrItemPtr> OCR_QUEUE;
	// 推理映射
	typedef std::unordered_map<std::string, InferencePtr> INFER_MAP;
	// 模型列表
	typedef std::vector<InferencePtr> INFERS;
	// 场景列表
	typedef std::vector<SceneInfo> SCENES;
	// 场景模型
	typedef std::tuple<std::string, SceneInfo, InferencePtr> SCENE_INFE;
	// 场景模型表
	typedef std::vector<SCENE_INFE> SCENE_INFES;
	// 设备场景
	typedef std::unordered_map<std::string, SCENES> DEV_SCENES;
public:
	Engine();
	virtual ~Engine();

public:
	// 启动引擎
	void Start();
	// 停止引擎
	void Stop();
	// 添加识别项
	void Push(OcrItemPtr item);
	// 手动载入模型
	bool LoadModel(std::string);

protected:
	// 初始化模型
	void SyncModel();
	// 同步场景
	void SyncScene();
	// 获取识别项
	OcrItemPtr Pop();
	// 后台识别线程
	void _Recognize();
	// 数据同步线程
	void _Synchronize();
	// 图片推理
	size_t _Inference(SCENE_INFES infes, OcrItemPtr item);

protected:
	// 运行标志
	bool m_run;
	// 识别线程
	std::thread m_ocr_thread;
	// 同步线程
	std::thread m_sync_thread;
	// 识别列表
	OCR_QUEUE m_queue;
	// 识别大锁
	std::mutex m_ocr_lock;
	// 推理大锁
	std::mutex m_infer_lock;
	// 推理模型
	INFER_MAP  m_infer_map;
	// 设备场景
	DEV_SCENES m_device_scenes;
	// 场景大锁
	std::mutex m_scene_lock;
	// 最近时长
	std::queue<double> m_times;
	// 平均市场
	double m_avg_time;
};

typedef std::shared_ptr<Engine> EnginePtr;